#ifndef CAR_LIST_H

#include "car_list.h"
#define CAR_LIST_H 1

#endif 

#include <stdlib.h>

void car_list_init(car_list_t *list)
{
    list->head = NULL; 
}

int car_list_len(car_list_t *list)
{
    int i = 0; 
    car_node_t *head = list->head; 
    
    for (; head; head = head->next, i++); 
    return i; 
}


static car_node_t *new_node(void *data)
{
    uint8_t i, len;
    car_node_t *node = (car_node_t *)malloc(sizeof(car_node_t));     
    node->data = (CAR_Unit *)malloc(sizeof(CAR_Unit));
    
    CAR_Unit *p = (CAR_Unit *)data;
    //node->data = data; 
    node->data->dead_time = p->dead_time;
    
    if(p->car_len < MAX_UNIT_PARKING_CAR_NUM_LEN)
        len = p->car_len;
    else
        len = MAX_UNIT_PARKING_CAR_NUM_LEN;
        
    node->data->car_len = len;
    for(i=0; i<len; i++)   
    {
        node->data->car_num[i] = p->car_num[i];
    }
    node->data->car_num[i] = '\0';
    
    node->next = NULL; 
    return node; 
}

static int get_index_by_node(car_list_t *list, car_node_t *p)
{
    int i; 
    car_node_t *t = list->head; 
    for (i = 0; t != p; t = t->next, i++); 
    return i; 
}

void car_list_append(car_list_t *list, void *data)
{
    car_node_t *head = list->head, *car_node = new_node(data); 
    
    if (head){
        for (; head->next; head = head->next); //goto the last node
        head->next = car_node; 
    }else list->head = car_node; 
}

int car_list_pop_tail(car_list_t *list)
{
    car_node_t *head = list->head; 
    
    if (!head) return 0; //only 0 eles, pop fail
    
    if (!(head->next)){ //only 1 node , pop it.
        free(head->data);
        head->data = NULL;
        free(head); 
        list->head = NULL; 
        return 1; 
    }
    
    for (; head->next->next; head = head->next); //goto the last second node
    free(head->next->data);
    head->next->data = NULL;
    free(head->next); 
    head->next = NULL; 
    return 1; 
}

int car_list_pop(car_list_t *list, int pos)
{
    int i = 0; 
    car_node_t *head = list->head, *temp = head; 
    
    if (!head) return 0; //no nodes at all
    
    for (; temp && i != pos; temp = temp->next, i++);  //get the node on position pos
    
    if (!temp) return 0; //unavaliable pos input:go through the list but no position equal pos.temp == NULL means we cycle the list
    
    if (temp == head){ //if pop node is the head node
        list->head = head->next; 
        free(head->data);
        free(head); 
        return 1; 
    }
    
    for (; head->next != temp; head = head->next); //else goto the pop node's pre node
    
    head->next = temp->next; 
    free(temp->data);
    free(temp); 
    return 1; 
}

void destroy_car_list(car_list_t *list)
{
    while(car_list_pop_tail(list));
}

//0: failed, 1: success
int car_list_compare(car_list_t *list, uint8_t *carnum, uint32_t current_time)
{
    int i, j;
    
    int llen = car_list_len(list);
    uint8_t car_temp[9] = "";
    int len = strlen(carnum);
    memcpy(car_temp, carnum, len);
    car_node_t *n = list->head;
        
    for(i=0; i<llen; i++)
    {
        for(j=len; j>0; j--)
        {
            if(n->data->car_num[j-1] != car_temp[j-1])
                break;
        }
        
        if(j == 0)  //check car_num right
        {
            if(n->data->dead_time < current_time)  //check dead_time if over.
                j=0;
            else
                j=1;
                
            car_list_pop(list, i);
            return j;
        }
        n=n->next;
    }
    
    return 0;
}

//This function will get err in keil
int car_list_get(car_list_t *list, int pos, void **data_ptr)
{
    car_node_t *head = list->head; 
    int i = 0; 
    
    for (; head; head = head->next, i++){
        if (i == pos) {
            *data_ptr = head->data; 
            return 1; 
        }
    }
    return 0; 
}

int car_list_set(car_list_t *list, int pos, void *data)
{
    car_node_t *t; 
    int i;
    
    for (t = list->head, i = 0; t; t = t->next, i++){
        if (i == pos) {
            t->data = data; 
            return 1; 
        }
    }
    return 0; 
}

int car_list_index(car_list_t *list, void *data)
{
    car_node_t *t = list->head; 
    int i = 0; 
    
    for (; t; t = t->next, i++){
        if (t->data == data) return i; 
    }
    return -1; 
}


void car_list_cycle(car_list_t *list, void **data_ptr, int * pos_ptr)
{
    static car_node_t *p = NULL;
    if (!p) p = list->head; 
    
    *data_ptr = p->data;//get data
    *pos_ptr = get_index_by_node(list, p); //get index
    //move
    p = p->next;
}

CAR_Unit * create_new_car_unit(uint32_t dead_time, uint8_t car_len, uint8_t* car_num)
{
    CAR_Unit * u = (CAR_Unit *)malloc(sizeof(CAR_Unit));
    printf("\r\nsizeof(CAR_Unit):%d\r\n", sizeof(CAR_Unit));
    
    u->dead_time = dead_time;
    uint8_t i, len;
    if(car_len < MAX_UNIT_PARKING_CAR_NUM_LEN)
        len = car_len;
    else
        len = MAX_UNIT_PARKING_CAR_NUM_LEN;
        
    u->car_len = len;
    for(i=0; i<len; i++)
    {
        u->car_num[i] = car_num[i];
    }
    
    return u;
}






